package com.zed.api.domain.currentuser;

import java.util.function.Function;

/**
 * 当前用户工具类
 * @author huangkh
 */
public abstract class CurrentUserUtils {

	private volatile static CurrentUserProvider PROVIDER ;
	
	/**
	 * 获取当前用户
	 * @return {@link CurrentUser},可能返回null.
	 */
	public static CurrentUser getCurrentUser() {
		CurrentUser result = null;
		if (PROVIDER != null) {
			result = PROVIDER.getCurrentUser();
		}

		return result;
	}
	
	/**
	 * 获取当前用户的账号，账号为null时返回匿名账号
	 * <br>
	 * 当前用户的账号为null时，使用匿名账号代替。
	 * @return {@link Account}
	 */
	public static Account getAccountWithCurrentUser() {
		CurrentUser currentUser = getCurrentUser();
		if (currentUser == null) return null;
		
		return getAccountWithCurrentUser(currentUser);
	}
	
	/**
	 * 从当前用户适配{@code adaptType}对象实例
	 * @param <T>
	 * @param adaptType {@link Class},适配对象
	 * @return {@link T},不支持适配则返回null.
	 */
	public static <T> T adaptToWithCurrentUser(Class<T> adaptType) {
		CurrentUser currentUser = getCurrentUser();
		if (currentUser == null) return null;
		
		return currentUser.adapt(adaptType);
	}
	
	/**
	 * 获取当前用户的账号，账号为null时返回匿名账号
	 * <br>
	 * 当{@code currentUser}的账号为null时，使用匿名账号代替。
	 * @param currentUser {@link CurrentUser},当前用户
	 * @return {@link Account}
	 */
	public static Account getAccountWithCurrentUser(CurrentUser currentUser) {
		Account result = currentUser.getAccount();
		if (result ==  null) {
			result = AnonymousAccount.getInstance();
		}
		return result;
	}
	
	
	/**
	 * 绑定当前用户提供者
	 * @param provider {@link CurrentUserProvider},当前用户提供者
	 * @return {@link CurrentUserProvider}
	 */
	public synchronized static void bind(CurrentUserProvider provider) {
		PROVIDER = provider;
	}
	
	/**
	 * 绑定当前用户提供者
	 * @param action {@link Function},绑定操作
	 */
	public synchronized static void bind(Function<CurrentUserProvider, CurrentUserProvider> action) {
		if (action != null) {
			PROVIDER = action.apply(PROVIDER);
		}
	}
}
